package com.njtoyo.taxi.admin.service.open.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.njtoyo.taxi.admin.library.Const;
import com.njtoyo.taxi.admin.logic.open.OnCallBacklogLogic;
import com.njtoyo.taxi.admin.mapper.master.entity.OnCallBacklog;
import com.njtoyo.taxi.admin.mapper.master.enums.OnCallBackLogSourcePlatform;
import com.njtoyo.taxi.admin.mapper.master.mapper.OnCallBacklogMapper;
import com.njtoyo.taxi.admin.rest.presenter.open.on_call.OrderReplyPresenter;
import com.njtoyo.taxi.admin.rest.wrapper.open.on_call.CallbackWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.open.on_call.CreateWrapper;
import com.njtoyo.taxi.admin.service.open.OnCallService;
import com.taxi.entity.common.RestResult;
import com.taxi.entity.common.ResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
@DS(Const.PRIMARY_DS)
public class OnCallServiceImpl implements OnCallService {
    
    @Autowired
    private OnCallBacklogMapper onCallBacklogMapper;
    
    @Autowired
    private OnCallBacklogLogic onCallBacklogLogic;

    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;
    
    @Override
    public RestResult<OrderReplyPresenter> create(CreateWrapper wrapper, OnCallBackLogSourcePlatform app) {
        Long expectTimestamp = wrapper.getExpectTimestamp();
        if (expectTimestamp == 0) {
            expectTimestamp = (new Date()).getTime();
        }

        OnCallBacklog backlog = new OnCallBacklog();
        backlog.setCallerMobileNumber(wrapper.getCallerMobileNumber())
                .setCustomerName(wrapper.getCustomer().getName())
                .setCustomerMobileNumber(wrapper.getCustomer().getMobileNumber())
                .setOriginName(wrapper.getOrigin().getName())
                .setOriginAdcode(wrapper.getOrigin().getAdcode())
                .setOriginPoint(wrapper.getOrigin().getLocation())
                .setDestinationAdcode(wrapper.getDestination().getAdcode())
                .setDestinationName(wrapper.getDestination().getName())
                .setDestinationPoint(wrapper.getDestination().getLocation())
                .setExpectTimestamp(expectTimestamp)
                .setContactWho(wrapper.getContactWho())
                .setCallbackUrl(wrapper.getCallbackUrl())
                .setSourcePlatform(app)
                .setCreatedAt(new Date())
                .setUpdatedAt(new Date());

        onCallBacklogMapper.insert(backlog);
        
        OrderReplyPresenter res = new OrderReplyPresenter();
        res.setId(backlog.getId());
        
        if (expectTimestamp < DateUtil.offsetMinute(new Date(), 30).getTime()) {
            onCallBacklogLogic.sendOnCallBacklog(backlog.getId());
        } else {
            taskScheduler.schedule(() -> onCallBacklogLogic.sendOnCallBacklog(backlog.getId()), new Date(expectTimestamp));
        }

        return RestResult.success(res);
    }

    @Override
    public RestResult callback(CallbackWrapper wrapper) {
        OnCallBacklog backlog = onCallBacklogMapper.selectOne(Wrappers.<OnCallBacklog>lambdaQuery()
                .eq(OnCallBacklog::getSimpleCallId, wrapper.getId()));
        
        if (Objects.isNull(backlog)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        if (Objects.isNull(backlog.getCallbackUrl())) {
            return RestResult.failed("未填写地址，无需回调");
        }
        Map<String, Object> body = new HashMap<>();
        body.put("id", SecureUtil.md5(backlog.getId().toString()));
        body.put("type", wrapper.getType().name());
        body.put("data", wrapper.getData());

        onCallBacklogLogic.sendCallback(backlog.getCallbackUrl(), body);
        return RestResult.success();
    }
}
